﻿
Imports ProtoBuf
Imports System.Runtime.Serialization
Imports Framework

<DataContract, ProtoContract>
Public Class CDefaultValueList : Inherits List(Of CDefaultValue)

	'Pre-constructors
	Shared Sub New()
		CProto.Prepare(Of CDefaultValueList)()
	End Sub

	'Constructor
	Public Sub New()

	End Sub
	Public Sub New(db As CDataSrc)
		Me.New(db.ExecuteDataSet(CDataSrc.SQL_TO_LIST_DEFAULTS_BY_TABLE).Tables(0))
	End Sub
	Public Sub New(dt As DataTable)
		MyBase.New(dt.Rows.Count)

		Dim last As CDefaultValue = Nothing
		For Each dr As DataRow In dt.Rows
			Dim dv As New CDefaultValue(dr)
			If dv.TableName.StartsWith("sys.") OrElse dv.TableName.StartsWith("dbo.sys") Then Continue For

			Me.Add(dv)
			last = dv
		Next
	End Sub

	'Aggregation
	Public ReadOnly Property MD5 As Guid
		Get
			Dim list As New List(Of Guid)(Me.Count)
			For Each i As CDefaultValue In Me
				list.Add(i.MD5)
			Next
			Return CBinary.MD5_(list)
		End Get
	End Property

	Public ReadOnly Property NamesAbc_ As String
		Get
			Return CUtilities.ListToString(NamesAbc)
		End Get
	End Property
	Public ReadOnly Property NamesAbc As List(Of String)
		Get
			NamesAbc = Names
			NamesAbc.Sort()
		End Get
	End Property
	Public ReadOnly Property Names As List(Of String)
		Get
			Dim list As New List(Of String)(Me.Count)
			For Each i As CDefaultValue In Me
				list.Add(i.Name)
			Next
			Return list
		End Get
	End Property


	'Index/Retrieval
	Public Function GetByName(name As String) As CDefaultValue
		Dim pk As CDefaultValue = Nothing
		IndexByName.TryGetValue(name.ToLower, pk)
		Return pk
	End Function
	Public Function GetByTable(name As String) As CDefaultValue
		Dim pk As CDefaultValue = Nothing
		IndexByTable.TryGetValue(name.ToLower, pk)
		Return pk
	End Function
	Public Function GetByHash(md5 As Guid) As CDefaultValue
		Dim pk As CDefaultValue = Nothing
		Index.TryGetValue(md5, pk)
		Return pk
	End Function

	Public Function Has(name As String) As Boolean
		Return IndexByName.ContainsKey(name.ToLower)
	End Function
	Public Function Has(md5 As Guid) As Boolean
		Return Index.ContainsKey(md5)
	End Function

	Private m_index As Dictionary(Of Guid, CDefaultValue)
	Private m_indexByName As Dictionary(Of String, CDefaultValue)
	Private m_indexByTable As Dictionary(Of String, CDefaultValue)
	Public ReadOnly Property Index As Dictionary(Of Guid, CDefaultValue)
		Get
			If IsNothing(m_index) Then
				Dim temp As New Dictionary(Of Guid, CDefaultValue)
				For Each i As CDefaultValue In Me
					temp.Add(i.MD5, i)
				Next
				m_index = temp
			End If
			Return m_index
		End Get
	End Property


	Public ReadOnly Property IndexByName As Dictionary(Of String, CDefaultValue)
		Get
			If IsNothing(m_indexByName) OrElse Me.Count <> m_indexByName.Count Then
				Dim temp As New Dictionary(Of String, CDefaultValue)
				For Each i As CDefaultValue In Me
					temp.Add(i.Name.ToLower, i)
				Next
				m_indexByName = temp
			End If
			Return m_indexByName
		End Get
	End Property



	Public ReadOnly Property IndexByTable As Dictionary(Of String, CDefaultValue)
		Get
			If IsNothing(m_indexByTable) OrElse Me.Count <> m_indexByTable.Count Then
				Dim temp As New Dictionary(Of String, CDefaultValue)
				For Each i As CDefaultValue In Me
					temp.Add(i.TableName.ToLower, i)
				Next
				m_indexByTable = temp
			End If
			Return m_indexByTable
		End Get
	End Property

	'Diff

	Public Function Diff(ref As CDefaultValueList) As CDefaultValueDiff
		Return New CDefaultValueDiff(Me, ref)
	End Function

End Class
